uniform sampler2D defColorTex;
uniform sampler2D defPosTex;
uniform sampler2D defNormalTex;
uniform sampler2D rsmPosTex;
uniform sampler2D rsmNormalTex;
uniform sampler2D rsmFluxTex;
//uniform sampler2D rsmDepthTex;
uniform sampler2D lightsTex;

uniform float d1 = 1.0;
uniform float d2 = 0.0;
uniform float d3 = 0.0;

uniform float r1 = 0.0;
uniform float r2 = 0.0;
uniform float r3 = 0.0;
uniform float r4 = 0.0;

uniform float f1 = 0.0;
uniform float f2 = 0.0;
uniform float f3 = 0.0;

uniform float lightsFact = 1.0;
uniform float indirLightFact = 1.0;

vec3	unpackNormal( vec3 norm )
{
	return (norm - 0.5) * 2.0;
}

vec3	unpackPos( vec3 pos )
{
	//return (pos - 0.5) * 100.0;	//[-50;50]
	return (pos - 0.5) * 40.0;		//[-20;20]
}

vec4	rsmColor(vec3 dPos,vec3 dNorm)
{
	vec4	dColor = vec4(0.0);
	//vec4	addedColor = vec4(0);
	//vec4	addedColor1 = vec4(0);
	//vec4	addedColor2 = vec4(0);
	for( int x = 0; x < 8; x++ )
	for( int y = 0; y < 8; y++ )
	{
		//1/64 = 0.015625
		//1/32 = 0.03125
		//1/16 = 0.0625
		//1/8  = 0.125
		vec2 coord = vec2( 0.0625 + x * 0.125, 0.0625 + y * 0.125 );
		vec4 xPos = texture2D( rsmPosTex, coord );
		vec4 xNormal = texture2D( rsmNormalTex, coord );
		vec4 xFlux = texture2D( rsmFluxTex, coord );

		xNormal.xyz = unpackNormal( xNormal.xyz);
		xNormal.xyz = normalize( xNormal.xyz );
		xPos.xyz = unpackPos(xPos.xyz);
		
		float fact = clamp( dot( xNormal.xyz, -dNorm ), 0.0, 1.0 );
		float dist = distance( xPos.xyz, dPos );
		//addedColor += fact * 0.01;
		//addedColor1 += 0.1 / dist;
		//addedColor2 += fact * 0.05 / dist;
		dColor += xFlux * fact * 0.05 / dist;
	}
	return dColor;
}

vec4	rsmColor1( sampler1D tex, int cnt, float scale, vec2 sCoord, vec3 dPos, vec3 dNorm )
{
	vec4	dColor = vec4(0.0);
	//vec4	addedColor = vec4(0);
	//vec4	addedColor1 = vec4(0);
	//vec4	addedColor2 = vec4(0);
	float step = 1.0 / cnt;
	float off = 1.0 / (cnt * 2.0);
	for( int x = 0; x < cnt; x++ )
	{
		vec2 coord = sCoord + texture1D( tex, float( off + x * step ) ).xy * scale;

		vec4 xPos = texture2D( rsmPosTex, coord );
		vec4 xNormal = texture2D( rsmNormalTex, coord );
		vec4 xFlux = texture2D( rsmFluxTex, coord );

		xNormal.xyz = unpackNormal( xNormal.xyz );
		xNormal.xyz = normalize( xNormal.xyz );
		xPos.xyz = unpackPos( xPos.xyz );
		
		float fact = clamp( dot( xNormal.xyz, -dNorm ), 0.0, 1.0 );
		float dist = distance( xPos.xyz, dPos );
		//addedColor += fact * 0.01;
		//addedColor1 += 0.1 / dist;
		//addedColor2 += fact * 0.05 / dist;
		dColor += xFlux * fact * 0.05 / dist;
	}
	return dColor;
}

void main()
{
	vec4 dColor = texture2D( defColorTex, gl_TexCoord[0].st );
	vec4 dPos = texture2D( defPosTex, gl_TexCoord[0].st );
	vec4 dNormal = texture2D( defNormalTex, gl_TexCoord[0].st );
	vec4 rPos = texture2D( rsmPosTex, gl_TexCoord[0].st );
	vec4 rNormal = texture2D( rsmNormalTex, gl_TexCoord[0].st );
	vec4 rFlux = texture2D( rsmFluxTex, gl_TexCoord[0].st );
	//vec4 rDepth = texture2D( rsmDepthTex, gl_TexCoord[0].st );
	vec4 lightColor = texture2D( lightsTex, gl_TexCoord[0].st );
	
	vec2	shadowCoord = vec2( dPos.w, dNormal.w );

	dNormal.xyz = unpackNormal( dNormal.xyz );
	//rNormal.xyz = unpackNormal( rNormal.xyz );
	
	rPos.xyz = unpackPos( rPos.xyz );
	dPos.xyz = unpackPos( dPos.xyz );

	vec4	rsmCol = rsmColor(dPos.xyz,normalize(dNormal.xyz));
	//vec4	rsmCol = rsmColor1(distTex, distSamples, distScale, shadowCoord, dPos.xyz, normalize(dNormal.xyz));
	//dColor += rsmCol * indirLightFact + lightColor * lightsFact;
	dColor *= vec4(dColor.a) + rsmCol * indirLightFact + lightColor * lightsFact;

	dColor =
		d1 * dColor
	+	d2 * dPos
	+	d3 * dNormal

//	+	r1 * vec4(rDepth)
//	+	r1 * vec4(rFlux.a)
//	+	r1 * vec4(rPos.z)
//	+	r1 * vec4(shadowCoord, 0.0, 0.0)
	+	r1 * rsmCol

	+	r2 * rPos
	+	r3 * rNormal
	+	r4 * rFlux

	+	f1 * lightColor
	+	f2 * vec4(lightColor.a)
/*
	+	f1 * addedColor
	+	f2 * addedColor1
	+	f3 * addedColor2
*/
	;

	gl_FragColor = dColor;
}
